home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
tjgold.zip
/
INSTALL.001
/
GOLDLINK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-07-12
|
57KB
|
2,055 lines
{--------------------------------------------------------------------------}
{ Product: TechnoJock's Turbo Toolkit }
{ Version: GOLD }
{ Build: 1.01 }
{ }
{ Copyright 1986-1995 TechnoJock Software, Inc. }
{ All Rights Reserved }
{ Restricted by License }
{--------------------------------------------------------------------------}
{********************************}
{ Unit: GOLDLINK }
{********************************}
{++++++++++++++++++++++++++++++} unit GOLDLINK; {++++++++++++++++++++++++++++}
{$I GOLDFLAG.INC}
{$IFNDEF GOLDLINK}
{$DEFINE GOLDLINK}
{$ENDIF}
{++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
uses DOS, CRT, GoldStr, GoldMisc, GoldHard;
const
GCompleteString = 255;
TagBit = 0;
ColBit = 1;
type
{String singly-linked list}
StrItemPtr = ^StrItem;
StrItem = record
NextPtr: StrItemPtr;
Bits: byte;
StrPtr: ^string;
end; {StrItem}
StringLLPtr = ^StringLL;
StringLL = record
TotalNodes: integer;
ActiveNode: integer;
TopNode: integer;
StartNodePtr: StrItemPtr;
end; {StringLL}
{Single Linked List structures}
SingleNodePtr = ^SingleNodeRec;
SingleNodeRec = record
NextPtr: SingleNodePtr;
Bits: byte;
DataPtr: pointer;
DataSize: longint;
end; {SingleNodeRec}
SingleLLPtr = ^SingleLL;
SingleLL = record
StartNodePtr: SingleNodePtr;
EndNodePtr: SingleNodePtr;
TotalNodes: longint;
StrVars: boolean; {is data stored at node a string?}
Dirty: boolean;
end; {SingleLL}
{Double Linked List structures}
DoubleNodePtr = ^DoubleNodeRec;
DoubleNodeRec = record
NextPtr: DoubleNodePtr;
PrevPtr: DoubleNodePtr;
DataPtr: pointer;
DataSize: longint;
Bits: byte;
end; {DoubleNodeRec}
DLLWrongOrderFunc = function(SortID:shortint;Node1,Node2:DoubleNodePtr;Asc:boolean): boolean;
DLLGetStrFunc = function(Node:DoubleNodePtr;Start,Finish: longint): string;
DoubleLLPtr = ^DoubleLL;
DoubleLL = record
StartNodePtr: DoubleNodePtr;
EndNodePtr: DoubleNodePtr;
ActiveNodePtr: DoubleNodePtr;
TotalNodes: longint;
ActiveNodeNumber: longint;
SortID: shortInt;
SortAscending: boolean;
StrVars: boolean; {is data stored at node a string?}
Dirty: boolean;
WrongOrder: DLLWrongOrderFunc;
GetStr: DLLGetStrFunc;
end; {DoubleLL}
LinkSet = record
LastEcode: integer;
LastActiveDLL,
ActiveDLL: DoubleLLPtr;
LastActiveSLL,
ActiveSLL: SingleLLPtr;
NoFilesFound:string[12];
NoDirectories:string[12];
end; {linkset}
function LastLinkError: integer;
{Simple String Linked Lists}
procedure StrLLInit(var SL:StringLL);
function StrLLNodePtr(var SL:StringLL; Num:integer): StrItemPtr;
function StrLLAdd(var SL:StringLL; Str:String): integer;
function StrLLGetStr(var SL:StringLL;Num:integer): string;
procedure StrLLDestroy(var SL:StringLL);
function SLGetStr(P:pointer;Element,Start,Finish: longint): string;
function LoadWithDirectories(var SL:StringLL;ParentDir:string): integer;
function LoadWithDrives(var SL:StringLL): integer;
function LoadFileMasks(var SL:StringLL;MaskStr:string): integer;
function LoadAvailFileExtensions(var SL:StringLL;ParentDir:string): integer;
function LoadWithFiles(var SL:StringLL;Dir,Filemask:string;Attrib:word): integer;
{Important Procs!}
procedure SLLSetActiveList(var S:SingleLL);
procedure SLLActivatePrevList;
procedure DLLSetActiveList(var D:DoubleLL);
procedure DLLActivatePrevList;
{SLL Procs}
procedure InitSLL(var TheList:SingleLL);
function SLLNodePtr(NodeNumber:longint): SingleNodePtr;
function SLLAdd(var TheData;Size:longint): integer;
function SLLChange(Node:SingleNodePtr;var TheData;Size:longint): integer;
function SLLInsertBefore(Node:SingleNodePtr;var TheData;Size:longint): integer;
procedure SLLDelNode(Node:SingleNodePtr);
procedure SLLGetNodeData(Node:SingleNodePtr;Var TheData);
function SLLGetNodeDataSize(Node:SingleNodePtr):longint;
function SLLGetTagState(Num:longint):boolean;
procedure SLLSetBit(Node:SingleNodePtr; BitPos:byte; On:boolean);
function SLLGetBit(Node:SingleNodePtr; BitPos:byte): boolean;
procedure SLLDelAllStatus(BitPos:byte;On:boolean);
procedure SLLDestroy;
procedure SLLEmptyList;
{SLL custom string function}
procedure InitSLLStr(var TheList:SingleLL);
function SLLAddStr(Str:string):integer;
function SLLChangeStr(Node:SingleNodePtr;Str:string): integer;
function SLLGetStr(Num:longint):string;
function SLLGetNodeStr(Node:SingleNodePtr; Len:byte): string;
function SLLInsStrBefore(Node:SingleNodePtr;Str:string): integer;
{SLL custom file functions}
function SLLLoadFromFile(Filename:string):integer;
function SLLSaveToFile(Filename:string):integer;
{DLL Procs}
procedure DLLAssignWrongOrderFunc(Func:DLLWrongOrderFunc);
function DLLDefWrongOrder(SortID:shortint;Node1,Node2:DoubleNodePtr;Asc:boolean): boolean;
procedure DLLAssignGetStrFunc(Func:DLLGetStrFunc);
function DLLDefGetStr(Node:DoubleNodePtr;Start,Finish: longint): string;
procedure InitDLL(var TheList:DoubleLL);
procedure InitDLLStr(var TheList:DoubleLL);
procedure DLLFreeNodeData(Node:DoubleNodePtr);
function DLLNodePtr(NodeNumber:longint): DoubleNodePtr;
function DLLAdd(var TheData;Size:longint): integer;
function DLLAddStr(Str:string):integer;
function DLLChange(Node:DoubleNodePtr;var TheData;Size:longint): integer;
function DLLInsertBefore(Node:DoubleNodePtr;var TheData;Size:longint): integer;
procedure DLLDelNode(Node:DoubleNodePtr);
procedure DLLGetNodeData(Node:DoubleNodePtr;Var TheData);
function DLLGetNodeDataSize(Node:DoubleNodePtr):longint;
procedure DLLSwapNodes(Node1,Node2:DoubleNodePtr);
procedure DLLDelAllStatus(BitPos:byte;On:boolean);
procedure DLLAdvance(Amount:longint);
procedure DLLRetreat(Amount:longint);
procedure DLLJump(NodeNumber:longint);
procedure DLLShiftActiveNode(NewNode: DoubleNodePtr; NodeNumber: longint);
procedure DLLSort(SortID:shortint; Ascending:boolean);
function DLLGetNodeStr(Node:DoubleNodePtr;Start,Finish: longint): string;
function DLLGetStr(Num:longint): string;
function DLLGetTagState(Num:longint):boolean;
procedure DLLSetBit(Node:DoubleNodePtr; BitPos:byte; On:boolean);
function DLLGetBit(Node:DoubleNodePtr; BitPos:byte): boolean;
procedure DLLDestroy;
procedure DLLEmptyList;
function DLLLoadFromFile(Filename:string):integer;
function DLLSaveToFile(Filename:string):integer;
{internal}
function StrLLWidestLine(var SL:StringLL): byte;
function _SLLNodePtr(var TheList:SingleLL;NodeNumber:longint): SingleNodePtr;
function _SLLAdd(var TheList:SingleLL;var TheData;Size:longint): integer;
function _SLLChange(var TheList:SingleLL;Node:SingleNodePtr;var TheData;Size:longint): integer;
function _SLLInsertBefore(var TheList:SingleLL;Node:SingleNodePtr;var TheData;Size:longint): integer;
procedure _SLLDelNode(var TheList:SingleLL;Node:SingleNodePtr);
function _SLLGetTagState(var TheList:SingleLL;Num:longint):boolean;
procedure _SLLSetBit(var TheList:SingleLL;Node:SingleNodePtr; BitPos:byte; On:boolean);
procedure _SLLDelAllStatus(var TheList:SingleLL;BitPos:byte;On:boolean);
procedure _SLLDestroy(var TheList:SingleLL);
function _SLLAddStr(var TheList:SingleLL;Str:string):integer;
function _SLLChangeStr(var TheList:SingleLL;Node:SingleNodePtr;Str:string): integer;
function _SLLGetStr(var TheList:SingleLL;Num:longint):string;
function _SLLGetNodeStr(var TheList:SingleLL;Node:SingleNodePtr; Len:byte): string;
function _SLLInsStrBefore(var TheList:SingleLL;Node:SingleNodePtr;Str:string): integer;
function _SLLLoadFromFile(var TheList:SingleLL;Filename:string):integer;
var
LinkVars: LinkSet;
{+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
{**********************************}
{** Miscellaneous Routines **}
{**********************************}
function LastLinkError: integer;
{}
begin
LastLinkError := LinkVars.LastEcode;
end; { LastLinkError }
procedure SLLSetActiveList(var S:SingleLL);
{}
begin
with LinkVars do
begin
LastActiveSLL := ActiveSLL;
ActiveSLL := @S;
end;
end; {SLLSetActiveList}
procedure SLLActivatePrevList;
{}
begin
with LinkVars do
begin
ActiveSLL := LastActiveSLL;
LastActiveSLL := nil;
end;
end; { SLLActivatePrevList }
procedure DLLSetActiveList(var D:DoubleLL);
{}
begin
with LinkVars do
begin
LastActiveDLL := ActiveDLL;
ActiveDLL := @D;
end;
end; {DLLSetActiveList}
procedure DLLActivatePrevList;
{}
begin
with LinkVars do
begin
ActiveDLL := LastActiveDLL;
LastActiveDLL := nil;
end;
end; { DLLActivatePrevList }
{***********************************}
{** Simple String List Routines **}
{***********************************}
function StrLLNodePtr(var SL:StringLL; Num:integer): StrItemPtr;
{}
var
Counter: integer;
SIP: StrItemPtr;
begin
if Num < 1 then
StrLLNodePtr := nil
else
begin
SIP := SL.StartNodePtr;
Counter := 0;
repeat
inc(Counter);
if Counter <> Num then
SIP := SIP^.NextPtr;
until (Counter = Num) or (SIP = nil);
StrLLNodePtr := SIP;
end;
end; { StrLLNodePtr }
procedure StrLLInit(var SL:StringLL);
{}
begin
with SL do
begin
TotalNodes := 0;
TopNode := 0;
ActiveNode := 0;
StartNodePtr := nil;
end;
end; { StrLLInit }
function StrLLAdd(var SL:StringLL; Str:String): integer;
{
Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
}
var
NewPtr: StrItemPtr;
StrSize:integer;
begin
StrSize := succ(length(Str));
if GoldMemAvail < sizeof(SL.StartNodePtr^) + StrSize then
StrLLAdd := 1
else
begin
StrLLAdd := 0;
if SL.StartNodePtr = nil then
begin
getmem(SL.StartNodePtr,sizeof(SL.StartNodePtr^));
SL.ActiveNode := 1;
SL.TopNode := 1;
NewPtr := SL.StartNodePtr;
end
else
begin
NewPtr := StrLLNodePtr(SL,SL.TotalNodes);
getmem(NewPtr^.NextPtr,sizeof(NewPtr^.NextPtr^));
NewPtr := NewPtr^.NextPtr;
end;
inc(SL.TotalNodes);
with NewPtr^ do
begin
NextPtr := nil;
Bits := 0;
if Str = '' then
StrPtr := nil
else
begin
getmem(StrPtr,StrSize);
move(Str[0],StrPtr^,StrSize);
end;
end;
end;
end; { StrLLAdd }
function StrLLGetStr(var SL:StringLL;Num:integer): string;
{}
var SIP: StrItemPtr;
begin
SIP := StrLLNodePtr(SL,Num);
if SIP = nil then
StrLLGetStr := ''
else
begin
if SIP^.StrPtr = nil then
StrLLGetStr := ''
else
StrLLGetStr := SIP^.StrPtr^;
end;
end; { StrLLGetStr }
function StrLLWidestLine(var SL:StringLL): byte;
{INTERNAL}
var
W: byte;
I: integer;
begin
W := 0;
for I := 1 to SL.TotalNodes do
W := GetMax(W,length(StrLLGetStr(SL,I)));
StrLLWidestLine := W;
end; {StrLLWidestLine}
procedure StrLLDestroy(var SL:StringLL);
{Disposes of all memory allocated in the string linked-list}
var SIP1, SIP2: StrItemPtr;
begin
SIP1 := SL.StartNodePtr;
while SIP1 <> nil do
begin
SIP2 := SIP1^.NextPtr;
if SIP1^.StrPtr <> nil then
freemem(SIP1^.StrPtr,succ(length(SIP1^.StrPtr^)));
freemem(SIP1,sizeof(SIP1^));
SIP1 := SIP2;
end;
StrLLInit(SL);
end; { StrLLDestroy }
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function SLGetStr(P:pointer;Element,Start,Finish: longint): string;
{}
var Str:string;
begin
Str := StrLLGetStr(StringLLPtr(P)^,Element);
SLGetStr := padleft(Str,succ(Finish-Start),' ');
end; { SLGetStr }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
{**********************************}
{** StrLL Automatic Population **}
{**********************************}
function LoadWithDrives(var SL:StringLL): integer;
{Checks the system and updates the SLL with strings indicating all the valid
drives, in the format '[-A-]'
Return codes: 0 all is well!
1 Error creating list
}
var I, gResult: integer;
DrvCh: char;
begin
StrLLDestroy(SL);
LoadWithDrives := 0;
for I := 1 to LastDrv do
begin
DrvCh := DriveChar(I);
if DriveExists(DrvCh) then
gResult := StrLLAdd(SL,'[-'+DrvCh+'-]');
if gResult <> 0 then
begin
LoadWithDrives := 1;
exit;
end;
end;
end; { LoadWithDrives }
function LoadAvailFileExtensions(var SL:StringLL;ParentDir:string): integer;
{Populates the StrLL with file extensions within the ParentDir.
Return codes: 0 all is well!
1 Error creating list
2 Not a valid directory
}
var Extn,
CurDirStr: dirstr;
Found: boolean;
I, gResult: integer;
SrchRec: searchrec;
function InList: boolean;
{}
var Temp: boolean;
begin
I := 1;
Temp := false;
while (not Temp) and (I <= SL.TotalNodes) do
begin
Temp := ('*.'+Extn = StrLLGetStr(SL,I));
inc(I);
end;
InList := Temp;
end; { InList }
begin
StrLLDestroy(SL);
gResult := 0;
LoadAvailFileExtensions := 0;
CurDirStr := CurrentPathStr;
if not SetCurrentPath(ParentDir) then
LoadAvailFileExtensions := 2
else
begin
gResult := StrLLAdd(SL,'*.*');
if gResult = 0 then
begin
findfirst(SlashedDirectory(ParentDir)+'*.*',AnyFile,SrchRec);
while (DosError = 0) and (gResult = 0) do
begin
Extn := FileExt(SrchRec.Name);
if (length(Extn) > 1) and (not InList) then
begin
gResult := StrLLAdd(SL,'*.'+Extn);
if gResult <> 0 then
begin
LoadAvailFileExtensions := 1;
if SetCurrentPath(CurDirStr) then ; { do nothing }
exit;
end;
end;
findnext(SrchRec);
end;
if SetCurrentPath(CurDirStr) then ; { do nothing }
end;
end;
end; { LoadAvailFileExtensions }
function LoadWithDirectories(var SL:StringLL;ParentDir:string): integer;
{Populates the StrLL with all the subdirectories found in
ParentDir.
Return codes: 0 all is well!
1 Error creating list
2 Not a valid directory
}
var CurDirStr: dirstr;
SrchRec: SearchRec;
gResult: integer;
Attr: word;
begin
StrLLDestroy(SL);
LoadWithDirectories := 0;
CurDirStr := CurrentPathStr;
if SetCurrentPath(ParentDir) then
begin
findfirst(SlashedDirectory(ParentDir)+'*.*',Directory,SrchRec);
while (DosError = 0) do
begin
if ((SrchRec.Attr and Directory) = Directory) then
begin
if (SrchRec.Name <> '.') then
begin
gResult := StrLLAdd(SL,'['+SrchRec.Name+']');
if gResult <> 0 then
begin
LoadWithDirectories := 1;
if SetCurrentPath(CurDirStr) then ; { do nothing }
exit;
end;
end;
end;
findnext(SrchRec);
end;
if SL.TotalNodes = 0 then
gResult := StrLLAdd(SL,LinkVars.NoDirectories);
if SetCurrentPath(CurDirStr) then ; { do nothing }
end else
begin
LoadWithDirectories := 2;
end;
end; { LoadWithDirectories }
function LoadFileMasks(var SL:StringLL;MaskStr:string): integer;
{Populates the StrLL with specific file masks as indicated
in MaskStr, e.g. '*.pas *.inc *.asm'. This indicates
to the program which file types to make available.
Return codes: 0 all is well!
1 error creating list
}
var NumOfMasks,
I, gResult: integer;
Mask: string;
begin
StrLLDestroy(SL);
LoadFileMasks := 0;
I := 1;
NumOfMasks := WordCnt(MaskStr);
while I < succ(NumOfMasks) do
begin
Mask := ExtractWords(I,1,MaskStr);
gResult := StrLLAdd(SL,Mask);
if (gResult <> 0) then
begin
LoadFileMasks := 1;
exit;
end else
inc(I);
end;
end; { LoadFileMasks }
function LoadWithFiles(var SL:StringLL;Dir,Filemask:string;Attrib:word): integer;
{Populates the StrLL with all the matching files found in
the Dir directory. Note that Filemask may contain multiple
filemasks, e.g. '*.pas *.inc *.asm'.
Return codes: 0 all is well!
1 Error creating list
2 Not a valid directory
}
var CurDirStr: dirstr;
WrdCnt,
I, gResult: integer;
Mask: string;
SrchRec: SearchRec;
begin
I := 1;
StrLLDestroy(SL);
LoadWithFiles := 0;
CurDirStr := CurrentPathStr;
if SetCurrentPath(Dir) then
begin
WrdCnt := WordCnt(FileMask);
while (WrdCnt > 0) and (I < succ(WrdCnt)) do
begin
Mask := ExtractWords(I,1,FileMask);
findfirst(SlashedDirectory(Dir)+Mask,Attrib,SrchRec);
while DosError = 0 do
begin
if (SrchRec.Attr and Directory <> Directory) then
begin
gResult := StrLLAdd(SL,SrchRec.Name);
if (gResult <> 0) then
begin
LoadWithFiles := 1;
if SetCurrentPath(CurDirStr) then ; { do nothing }
exit;
end;
end;
findnext(SrchRec);
end;
inc(I);
end;
if SL.TotalNodes = 0 then
gResult := StrLLAdd(SL,LinkVars.NoFilesFound);
if SetCurrentPath(CurDirStr) then ; { do nothing }
end else
LoadWithFiles := 2;
end; { LoadWithFiles }
{***********************************}
{** Single Linked List Routines **}
{***********************************}
procedure InitSLL(var TheList:SingleLL);
{}
begin
with TheList do
begin
StartNodePtr := nil;
EndNodePtr := nil;
TotalNodes := 0;
StrVars := false;
Dirty := false;
end;
end; {InitSLL}
procedure InitSLLStr(var TheList:SingleLL);
{}
begin
InitSLL(TheList);
with TheList do
StrVars := true;
end; {InitSLLStr}
function _SLLNodePtr(var TheList:SingleLL;NodeNumber:longint): SingleNodePtr;
{}
var
I: integer;
SNP: SingleNodePtr;
begin
if (NodeNumber < 1) or (NodeNumber > TheList.TotalNodes) then
_SLLNodePtr := nil
else
begin
if NodeNumber = 1 then
_SLLNodePtr := TheList.StartNodePtr
else if NodeNumber = TheList.TotalNodes then
_SLLNodePtr := TheList.EndNodePtr
else
begin
SNP := TheList.StartNodePtr;
for I := 2 to NodeNumber do
SNP := SNP^.NextPtr;
_SLLNodePtr := SNP;
end;
end;
end; {_SLLNodePtr}
function SLLNodePtr(NodeNumber:longint): SingleNodePtr;
{}
begin
SLLNodePtr := _SLLNodePtr(LinkVars.ActiveSLL^,NodeNumber);
end; {SLLNodePtr}
procedure SLLFreeNodeData(var TheList:SingleLL;Node:SingleNodePtr);
{}
begin
if Node <> nil then
with Node^ do
begin
if (DataPtr <> Nil) and (DataSize > 0) then
freemem(DataPtr,DataSize);
DataPtr := nil;
DataSize := 0;
TheList.Dirty := true;
end;
end; {SLLFreeNodeData}
function SLLAddEngine(var TheList:SingleLL): integer;
{
Returns status indicating result of attempt to add.
Codes: 0 Success
1 Not enough memory
}
begin
if GoldMaxAvail < sizeof(TheList.StartNodePtr^) then
SLLAddEngine := 1 {not enough memory}
else with TheList do
begin
if StartNodePtr = nil then
begin
getmem(StartNodePtr,sizeof(StartNodePtr^));
EndNodePtr := StartNodePtr;
end
else
begin
getmem(EndNodePtr^.NextPtr,sizeof(EndNodePtr^));
EndNodePtr := EndNodePtr^.NextPtr;
end;
EndNodePtr^.NextPtr := nil;
inc(TotalNodes);
Dirty := true;
SLLAddEngine := 0;
end;
end; {SLLAddEngine}
function _SLLAdd(var TheList:SingleLL;var TheData;Size:longint): integer;
{
Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
}
var Temp:integer;
begin
Temp := SLLAddEngine(TheList);
if Temp <> 0 then
_SLLAdd := Temp
else with TheList do
begin
{now add the data to the node data pointer}
if GoldMaxAvail < Size then
begin
_SLLAdd := 2; {not enough memory for data}
EndNodePtr^.DataSize := 0;
EndNodePtr^.DataPtr := nil;
end
else
begin
if Size > 0 then
begin
getmem(EndNodePtr^.DataPtr,Size);
move(TheData,EndNodePtr^.DataPtr^,Size);
end
else
EndNodePtr^.DataPtr := nil;
EndNodePtr^.DataSize := Size;
EndNodePtr^.Bits := 0;
_SLLAdd := 0;
end;
end;
end; {_SLLAdd}
function SLLAdd(var TheData;Size:longint): integer;
{}
begin
SLLAdd := _SLLAdd(LinkVars.ActiveSLL^,TheData,Size);
end; {SLLAdd}
function _SLLAddStr(var TheList:SingleLL;Str:string):integer;
{}
var
Temp,L: integer;
begin
Temp := SLLAddEngine(TheList);
if Temp <> 0 then
_SLLAddStr := Temp
else with TheList do
begin
L := length(Str);
if GoldMaxAvail < succ(L) then
begin
_SLLAddStr := 2; {not enough memory for data}
EndNodePtr^.DataSize := 0;
EndNodePtr^.DataPtr := nil;
exit;
end;
if L > 0 then
begin
getmem(EndNodePtr^.DataPtr,succ(L));
move(Str,EndNodePtr^.DataPtr^,succ(L));
end
else
EndNodePtr^.DataPtr := nil;
EndNodePtr^.DataSize := succ(L);
EndNodePtr^.Bits := 0;
_SLLAddStr := 0;
end;
end; {_SLLAddStr}
function SLLAddStr(Str:string):integer;
{}
begin
SLLAddStr := _SLLAddStr(LinkVars.ActiveSLL^,Str);
end; {SLLAddStr}
function _SLLChange(var TheList:SingleLL;Node:SingleNodePtr;var TheData;Size:longint): integer;
{ Returns status indicating result of the change attempt
Codes: 0 Success
2 Not enough memory for data
3 Invalid Node Ptr
}
begin
if node = nil then
_SLLChange := 3
else
begin
SLLFreeNodeData(TheList,Node);
if GoldMaxAvail < Size then
_SLLChange := 2
else
begin
_SLLChange := 0;
getmem(Node^.DataPtr,Size);
move(TheData,Node^.DataPtr^,Size);
Node^.DataSize := Size;
end;
end;
end; {_SLLChange}
function SLLChange(Node:SingleNodePtr;var TheData;Size:longint): integer;
{}
begin
SLLChange := _SLLChange(LinkVars.ActiveSLL^,Node,TheData,Size);
end; {SLLChange}
function _SLLChangeStr(var TheList:SingleLL;Node:SingleNodePtr;Str:string): integer;
{ Returns status indicating result of the change attempt
Codes: 0 Success
2 Not enough memory for data
3 Invalid Node Ptr
}
var L: byte;
begin
if node = nil then
_SLLChangeStr := 3
else
begin
SLLFreeNodeData(TheList,Node);
L := succ(length(Str));
if GoldMaxAvail < L then
_SLLChangeStr := 2
else
begin
_SLLChangeStr := 0;
if L > 1 then {not empty string}
begin
getmem(Node^.DataPtr,L);
move(Str,Node^.DataPtr^,L);
Node^.DataSize := L;
end;
end;
end;
end; {_SLLChangeStr}
function SLLChangeStr(Node:SingleNodePtr;Str:string): integer;
{}
begin
SLLChangeStr := _SLLChangeStr(LinkVars.ActiveSLL^,Node,Str);
end; {SLLChangeStr}
function _SLLInsertBefore(var TheList:SingleLL;Node:SingleNodePtr;var TheData;Size:longint): integer;
{ Returns status indicating result of attempt to insert
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
}
var Temp,PP: SingleNodePtr;
begin
if Node = nil then
_SLLInsertBefore := _SLLAdd(TheList,TheData,Size)
else if GoldMaxAvail < sizeof(Node^) then
_SLLInsertBefore:= 1 {not enough memory}
else with TheList do
begin
getmem(Temp,sizeof(Temp^));
Dirty := true;
if Node = StartNodePtr then {add to head of list}
begin
Temp^.NextPtr := StartNodePtr;
StartNodePtr := Temp;
end
else
begin
PP := StartNodePtr;
while (PP^.NextPtr <> nil) and (PP^.NextPtr <> Node) do
PP := PP^.NextPtr;
if PP^.NextPtr = nil then
begin
_SLLInsertBefore := 3;
freemem(Temp,sizeof(Temp^));
exit;
end;
Temp^.NextPtr := PP^.NextPtr;
PP^.NextPtr := Temp;
end;
inc(TotalNodes);
Node^.Bits := 0;
if GoldMaxAvail < Size then
begin
_SLLInsertBefore := 2; {not enough memory for data}
Node^.DataSize := 0;
Node^.DataPtr := nil;
end
else
begin
if Size > 0 then
begin
getmem(Temp^.DataPtr,Size);
move(TheData,Temp^.DataPtr^,Size);
end
else
Temp^.DataPtr := nil;
Temp^.DataSize := Size;
_SLLInsertBefore := 0;
end;
end;
end; {_SLLInsertBefore}
function SLLInsertBefore(Node:SingleNodePtr;var TheData;Size:longint): integer;
{}
begin
SLLInsertBefore := _SLLInsertBefore(LinkVars.ActiveSLL^,Node,TheData,Size);
end; {SLLInsertBefore}
function _SLLInsStrBefore(var TheList:SingleLL;Node:SingleNodePtr;Str:string): integer;
{}
begin
if Str = '' then
_SLLInsStrBefore := _SLLInsertBefore(TheList,Node,Str,0)
else
_SLLInsStrBefore := _SLLInsertBefore(TheList,Node,Str,succ(length(Str)));
end; {_SLLInsStrBefore}
function SLLInsStrBefore(Node:SingleNodePtr;Str:string): integer;
{}
begin
SLLInsStrBefore :=_SLLInsStrBefore(LinkVars.ActiveSLL^,Node,Str);
end; {SLLInsStrBefore}
procedure _SLLDelNode(var TheList:SingleLL;Node:SingleNodePtr);
{}
var PP: SingleNodePtr;
begin
if Node <> nil then with TheList do
begin
if Node = StartNodePtr then
StartNodePtr := StartNodePtr^.NextPtr
else
begin
PP := StartNodePtr;
while (PP^.NextPtr <> nil) and (PP^.NextPtr <> Node) do
PP := PP^.NextPtr;
if PP^.NextPtr = nil then
exit; {node not found; just exit}
if Node = EndNodePtr then
begin
EndNodePtr := PP;
EndNodePtr^.NextPtr := nil;
end
else
PP^.NextPtr := PP^.NextPtr^.NextPtr;
end;
SLLFreeNodeData(TheList,Node);
freemem(Node,sizeof(Node^));
dec(TotalNodes);
end;
end; {_SLLDelNode}
procedure SLLDelNode(Node:SingleNodePtr);
{}
begin
_SLLDelNode(LinkVars.ActiveSLL^,Node);
end; {SLLDelNode}
procedure SLLGetNodeData(Node:SingleNodePtr;Var TheData);
{}
begin
if Node <> nil then
move(Node^.DataPtr^,TheData,Node^.DataSize);
end; {SLLGetNodeData}
function SLLGetNodeDataSize(Node:SingleNodePtr):longint;
{}
begin
if Node <> nil then
SLLGetNodeDataSize := Node^.DataSize
else
SLLGetNodeDataSize := 0;
end; {SLLGetNodeDataSize}
function _SLLGetNodeStr(var TheList:SingleLL;Node:SingleNodePtr; Len:byte): string;
{}
var
Temp:string;
L:integer;
begin
if (Node = Nil)
or (Node^.DataPtr = Nil)
or (Node^.DataSize = 0) then
_SLLGetNodeStr := ''
else
begin
if TheList.StrVars then
begin
move(Node^.DataPtr^,Temp,Node^.DataSize);
_SLLGetNodeStr := Temp;
end
else
begin
if (len < 1) or (Len > Node^.DataSize) then
L := Node^.DataSize
else
L := Len;
move(Node^.DataPtr^,Temp[1],L);
Temp [0] := chr(L);
_SLLGetNodeStr := Temp;
end;
end;
end; {_SLLGetNodeStr}
function SLLGetNodeStr(Node:SingleNodePtr; Len:byte): string;
{}
begin
SLLGetNodeStr := _SLLGetNodeStr(LinkVars.ActiveSLL^,Node,Len);
end; {SLLGetNodeStr}
function _SLLGetStr(var TheList:SingleLL;Num:longint):string;
{}
var SNP: SingleNodePtr;
begin
SNP := _SLLNodePtr(TheList,Num);
if SNP = nil then
_SLLGetStr := ''
else
_SLLGetStr := _SLLGetNodeStr(TheList,SNP,0);
end; {_SLLGetStr}
function SLLGetStr(Num:longint):string;
{}
begin
SLLGetStr := _SLLGetStr(LinkVars.ActiveSLL^,Num);
end; {SLLGetStr}
procedure _SLLSetBit(var TheList:SingleLL;Node:SingleNodePtr; BitPos:byte; On:boolean);
{}
begin
if Node <> nil then
begin
SetBitStatus(Node^.Bits,BitPos,On);
TheList.Dirty := true;
end;
end; { _SLLSetBit }
procedure SLLSetBit(Node:SingleNodePtr; BitPos:byte; On:boolean);
{}
begin
_SLLSetBit(LinkVars.ActiveSLL^,Node,BitPos,On);
end; {SLLSetBit}
function SLLGetBit(Node:SingleNodePtr; BitPos:byte): boolean;
{}
begin
if Node <> nil then
SLLGetBit := GetBitStatus(Node^.Bits,BitPos)
else
SLLGetBit := false;
end; { SLLGetBit }
function _SLLGetTagState(var TheList:SingleLL;Num:longint):boolean;
{}
var SNP: SingleNodePtr;
begin
SNP := _SLLNodePtr(TheList,Num);
if SNP <> nil then
_SLLGetTagState := SLLGetBit(SNP,TagBit)
else
_SLLGetTagState := false;
end; {SLLGetTagState}
function SLLGetTagState(Num:longint):boolean;
{}
begin
SLLGetTagState := _SLLGetTagState(LinkVars.ActiveSLL^,Num);
end; {SLLGetTagState}
procedure _SLLDelAllStatus(var TheList:SingleLL;BitPos:byte;On:boolean);
{}
var
TempPtr,TempNextPtr: SingleNodePtr;
begin
if TheList.StartNodePtr <> nil then with TheList do
begin
TempPtr := StartNodePtr;
TempNextPtr := TempPtr^.NextPtr;
while TempNextPtr <> nil do
begin
if GetBitStatus(TempNextPtr^.Bits,BitPos) = On then
_SLLDelNode(TheList,TempNextPtr)
else
TempPtr := TempPtr^.NextPtr;
TempNextPtr := TempPtr^.NextPtr;
end;
if GetBitStatus(StartNodePtr^.Bits,BitPos) = On then
_SLLDelNode(TheList,StartNodePtr);
end;
end; {_SLLDelAllStatus}
procedure SLLDelAllStatus(BitPos:byte;On:boolean);
{}
begin
_SLLDelAllStatus(LinkVars.ActiveSLL^,BitPos,On);
end; {SLLDelAllStatus}
procedure _SLLDestroy(var TheList:SingleLL);
{}
var Temp1,Temp2: SingleNodePtr;
begin
Temp1 := TheList.StartNodePtr;
while Temp1 <> nil do
begin
Temp2 := Temp1^.NextPtr;
SLLFreeNodeData(TheList,Temp1);
freemem(Temp1,sizeof(Temp1^));
Temp1 := Temp2;
end;
TheList.StartNodePtr := nil;
TheList.EndNodePtr := nil;
TheList.TotalNodes := 0;
end; {_SLLDestroy}
procedure SLLDestroy;
{}
begin
_SLLDestroy(LinkVars.ActiveSLL^);
end; {SLLDestroy}
procedure SLLEmptyList;
{}
begin
SLLDestroy;
end; {SLLEmptyList}
{**************************}
{** SLL File Functions **}
{**************************}
function _SLLLoadFromFile(var TheList:SingleLL;Filename:string):integer;
{Opens a file as text, reads in each line as a node, then closes the file
Return codes: 0 all is well!
1 file not found
2 Error Reading file
3 Error creating list
}
var
F: text;
TempStr:string;
begin
assign(F, Filename);
{$I-}
reset(F);
{$I+}
if IOResult <> 0 then
_SLLLoadFromFile := 1
else
begin
_SLLDestroy(TheList); {empty the list}
while not eof(F) do
begin
{$I-}
readln(F,TempStr);
{$I+}
if IOResult <> 0 then
begin
close(F);
_SLLLoadFromFile := 2;
exit;
end;
if _SLLAddStr(TheList,TempStr) <> 0 then
begin
close(F);
_SLLLoadFromFile := 3;
exit;
end;
end;
close(F);
_SLLLoadFromFile := 0;
end;
end; {_SLLLoadFromFile}
function SLLLoadFromFile(Filename:string):integer;
{}
begin
SLLLoadFromFile := _SLLLoadFromFile(LinkVars.ActiveSLL^,Filename);
end; {SLLLoadFromFile}
function SLLSaveToFile(Filename:string):integer;
{Rewrites the file (erasing its contents) then saves the file SLL data
as strings in a text file
Return codes: 0 all is well!
1 Unable to open file
2 Error Writing file
}
var
F: text;
TempStr:string;
Temp1,Temp2: SingleNodePtr;
begin
assign(F, Filename);
{$I-}
rewrite(F);
{$I+}
if IOResult <> 0 then
SLLSaveToFile := 1
else
begin
Temp1 := LinkVars.ActiveSLL^.StartNodePtr;
while Temp1 <> nil do
begin
Temp2 := Temp1^.NextPtr;
{$I-}
writeln(F,SLLGetNodeStr(Temp1,255));
{$I+}
if IOResult <> 0 then
begin
close(F);
SLLSaveToFile := 2;
exit;
end;
Temp1 := Temp2;
end;
close(F);
SLLSaveToFile := 0
end;
end; {SLLSaveToFile}
{*********************************}
{** Double Link List Routines **}
{*********************************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function DLLDefWrongOrder(SortID:shortint;Node1,Node2:DoubleNodePtr;Asc:boolean): boolean;
{}
var
B1,B2:byte;
begin
if LinkVars.ActiveDLL^.StrVars then
begin
if Asc then
DLLDefWrongOrder := string(Node2^.DataPtr^) < string(Node1^.DataPtr^)
else
DLLDefWrongOrder := string(Node1^.DataPtr^) < string(Node2^.DataPtr^)
end
else
begin
move(Node1^.DataPtr^,B1,1);
move(Node2^.DataPtr^,B2,1);
if Asc then
DLLDefWrongOrder := B2 > B1
else
DLLDefWrongOrder := B1 > B2
end;
end; {DLLDefWrongOrder}
function DLLDefGetStr(Node:DoubleNodePtr;Start,Finish: longint): string;
{}
var
temp: string;
begin
if Start < 0 then Start := 0;
if Finish < 0 then Finish := 0;
{validate Start and Finish Parameters}
if ((Finish = 0) and (Start = 0))
or (Start > Finish) then {get full string}
begin
Start := 1;
Finish := 255;
end
else if Finish - Start > 254 then {too long to fit in string}
Finish := Start + 254;
if (Node = Nil)
or (Node^.DataPtr = Nil)
or (Node^.DataSize = 0)
or (Start > Node^.DataSize) then
DLLDefGetStr := ''
else
begin
if Finish > Node^.DataSize then
Finish := Node^.DataSize;
if Start = 0 then
inc(Start);
if LinkVars.ActiveDLL^.StrVars then
begin
move(Node^.DataPtr^,Temp,256);
DLLDefGetStr := copy(Temp,Start,succ(Finish-Start));
end
else
begin
move(mem[seg(Node^.DataPtr^):ofs(Node^.DataPtr^)+pred(Start)],Temp[1],succ(Finish-Start));
Temp [0] := chr(succ(Finish-Start));
DLLDefGetStr := Temp;
end;
end;
end; {DLLDefGetStr}
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure DLLAssignWrongOrderFunc(Func:DLLWrongOrderFunc);
{}
begin
if LinkVars.ActiveDLL <> nil then
LinkVars.ActiveDLL^.WrongOrder := Func;
end; {DLLAssignWrongOrderFunc}
procedure DLLAssignGetStrFunc(Func:DLLGetStrFunc);
{}
begin
LinkVars.ActiveDLL^.GetStr := Func;
end; {DLLAssignGetStrFunc}
procedure InitDLLEngine(var TheList:DoubleLL);
{}
begin
with TheList do
begin
StartNodePtr := nil;
EndNodePtr := nil;
ActiveNodePtr := nil;
TotalNodes := 0;
ActiveNodeNumber := 0;
SortID := 0;
SortAscending := true;
Dirty := false;
WrongOrder := DLLDefWrongOrder;
GetStr := DLLDefGetStr;
end;
end; {InitDLLEngine}
procedure InitDLL(var TheList:DoubleLL);
{}
begin
InitDLLEngine(TheList);
TheList.StrVars := false;
end; {InitDLL}
procedure InitDLLStr(var TheList:DoubleLL);
{}
begin
InitDLLEngine(TheList);
TheList.StrVars := true;
end; {InitDLLStr}
procedure DLLFreeNodeData(Node:DoubleNodePtr);
{INTERNAL}
begin
if Node <> nil then
with Node^ do
begin
if (DataPtr <> Nil) and (DataSize > 0) then
freemem(DataPtr,DataSize);
DataPtr := nil;
DataSize := 0;
LinkVars.ActiveDLL^.Dirty := true;
end;
end; {DLLFreeNodeData}
function DLLAddEngine: integer;
{ Adds node after the ActiveNodePtr, and increments the
ActiveNodePtr.
Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
}
var
Temp: DoubleNodePtr;
begin
DLLAddEngine := 0;
if GoldMaxAvail < sizeof(LinkVars.ActiveDLL^.StartNodePtr^) then
DLLAddEngine := 1 {not enough memory}
else with LinkVars.ActiveDLL^ do
begin
if StartNodePtr = nil then
begin
getmem(StartNodePtr,sizeof(StartNodePtr^));
StartNodePtr^.PrevPtr := nil;
StartNodePtr^.NextPtr := nil;
ActiveNodePtr := StartNodePtr;
ActiveNodeNumber := 1;
EndNodePtr := ActiveNodePtr;
end
else
begin
if ActiveNodePtr^.NextPtr = nil then {end of list}
begin
getmem(ActiveNodePtr^.NextPtr,sizeof(ActiveNodePtr^));
ActiveNodePtr^.NextPtr^.PrevPtr := ActiveNodePtr;
ActiveNodePtr := ActiveNodePtr^.NextPtr;
ActiveNodePtr^.NextPtr := nil;
inc(ActiveNodeNumber);
EndNodePtr := ActiveNodePtr;
end
else {insert a node}
begin
getmem(Temp,sizeof(Temp^));
ActiveNodePtr^.NextPtr^.PrevPtr := Temp;
Temp^.NextPtr := ActiveNodePtr^.NextPtr;
Temp^.PrevPtr := ActiveNodePtr;
ActiveNodePtr^.NextPtr := Temp;
ActiveNodePtr := Temp;
inc(ActiveNodeNumber);
end;
end;
inc(TotalNodes);
LinkVars.ActiveDLL^.Dirty := true;
end;
end; {DLLAddEngine}
function DLLAdd(var TheData;Size:longint): integer;
{ Adds node after the ActiveNodePtr, and increments the
ActiveNodePtr.
Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
99 List not active
}
var
Temp: integer;
begin
if LinkVars.ActiveDLL <> nil then
begin
Temp := DLLAddEngine;
if Temp <> 0 then
DLLAdd := Temp
else with LinkVars.ActiveDLL^ do
begin
{now add the data to the node data pointer}
if GoldMaxAvail < Size then
begin
DLLAdd := 2; {not enough memory for data}
ActiveNodePtr^.DataSize := 0;
ActiveNodePtr^.DataPtr := nil;
exit;
end;
if Size > 0 then
begin
getmem(ActiveNodePtr^.DataPtr,Size);
move(TheData,ActiveNodePtr^.DataPtr^,Size);
end
else
ActiveNodePtr^.DataPtr := nil;
ActiveNodePtr^.DataSize := Size;
ActiveNodePtr^.Bits := 0;
DLLAdd := 0;
end;
end
else
DLLAdd := 99;
end; {DLLAdd}
function DLLAddStr(Str:string):integer;
{}
var
Temp,L: integer;
begin
if LinkVars.ActiveDLL <> nil then
begin
Temp := DLLAddEngine;
if Temp <> 0 then
DLLAddStr := Temp
else with LinkVars.ActiveDLL^ do
begin
L := length(Str);
if GoldMaxAvail < succ(L) then
begin
DLLAddStr := 2; {not enough memory for data}
ActiveNodePtr^.DataSize := 0;
ActiveNodePtr^.DataPtr := nil;
exit;
end;
if L > 0 then
begin
getmem(ActiveNodePtr^.DataPtr,succ(L));
move(Str,ActiveNodePtr^.DataPtr^,succ(L));
end
else
ActiveNodePtr^.DataPtr := nil;
ActiveNodePtr^.DataSize := succ(L);
ActiveNodePtr^.Bits := 0;
DLLAddStr := 0;
end;
end
else
DLLAddStr := 99;
end; {DLLAddStr}
function DLLChange(Node:DoubleNodePtr;var TheData;Size:longint): integer;
{ Returns status indicating result of the change attempt
Codes: 0 Success
2 Not enough memory for data
3 Invalid Node Ptr
}
begin
if Node = nil then
DLLChange := 3
else
begin
DLLFreeNodeData(Node);
if GoldMaxAvail < Size then
DLLChange := 2
else
begin
DLLChange := 0;
getmem(Node^.DataPtr,Size);
move(TheData,Node^.DataPtr^,Size);
Node^.DataSize := Size;
end;
end;
end; {DLLChange}
function DLLInsertBefore(Node:DoubleNodePtr;var TheData;Size:longint): integer;
{ Returns status indicating result of attempt to insert
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
}
var
Temp: DoubleNodePtr;
begin
if node = nil then
DLLInsertBefore := DLLAdd(TheData,Size)
else if GoldMaxAvail < sizeOf(Node^) then
DLLInsertBefore:= 1 {not enough memory}
else with LinkVars.ActiveDLL^ do
begin
if Node = StartNodePtr then {add to head of list}
begin
getmem(Node^.PrevPtr,sizeof(Node^));
Node^.PrevPtr^.NextPtr := Node;
Node := Node^.PrevPtr;
Node^.PrevPtr := nil;
StartNodePtr := Node;
end
else {middle of list}
begin
getmem(Temp,sizeof(Temp^));
Node^.PrevPtr^.NextPtr := Temp;
Temp^.PrevPtr := Node^.PrevPtr;
Node^.PrevPtr := Temp;
Temp^.NextPtr := Node;
Node := Temp;
end;
inc(TotalNodes);
LinkVars.ActiveDLL^.Dirty := true;
ActiveNodeNumber := 1;
ActiveNodePtr := StartNodePtr;
if GoldMaxAvail < Size then
begin
DLLInsertBefore := 2; {not enough memory for data}
Node^.DataSize := 0;
Node^.DataPtr := nil;
end
else
begin
if Size > 0 then
begin
getmem(Node^.DataPtr,Size);
move(TheData,Node^.DataPtr^,Size);
end
else
Node^.DataPtr := nil;
Node^.DataSize := Size;
DLLInsertBefore := 0;
end;
end;
end; {DLLInsertBefore}
procedure DLLDelNode(Node:DoubleNodePtr);
{if a nil pointer is passed nothing is deleted}
begin
if Node <> nil then
with LinkVars.ActiveDLL^ do
begin
if ActiveNodePtr = Node then {move activeptr to next/prev entry in list}
begin
if ActiveNodePtr^.NextPtr = nil then
begin
dec(ActiveNodeNumber);
ActiveNodePtr := ActiveNodePtr^.PrevPtr;
end
else
ActiveNodePtr := ActiveNodePtr^.NextPtr;
end;
if Node = StartNodePtr then
begin
if Node^.NextPtr = nil then {only node in list}
begin
DLLFreeNodeData(Node);
freemem(StartNodePtr,sizeof(StartNodePtr^));
StartNodePtr := nil;
EndNodePtr := nil;
end
else
begin
StartNodePtr := StartNodePtr^.NextPtr;
StartNodePtr^.PrevPtr := nil;
DLLFreeNodeData(Node);
freemem(Node,sizeof(Node^));
end;
end
else {in body of list}
begin
Node^.PrevPtr^.NextPtr := Node^.NextPtr;
if Node = EndNodePtr then
EndNodePtr := EndNodePtr^.PrevPtr
else
Node^.NextPtr^.PrevPtr := Node^.PrevPtr;
DLLFreeNodeData(Node);
freemem(Node,sizeof(Node^));
end;
dec(TotalNodes);
end;
end; {DLLDelNode}
procedure DLLGetNodeData(Node:DoubleNodePtr;Var TheData);
{}
begin
if Node <> nil then
with Node^ do
if DataPtr <> Nil then
move(DataPtr^,TheData,DataSize);
end; {DLLGetNodeData}
function DLLGetNodeDataSize(Node:DoubleNodePtr):longint;
{}
begin
if Node <> nil then
with Node^ do
if DataPtr <> Nil then
DLLGetNodeDataSize := 0
else
DLLGetNodeDataSize := DataSize;
end; {DLLGetNodeDataSize}
procedure DLLSwapNodes(Node1,Node2:DoubleNodePtr);
{}
var
Ptr1: pointer;
Size1: longint;
Status1: byte;
Ecode: integer;
begin
Status1 := Node1^.Bits;
Node1^.Bits := Node2^.Bits;
Node2^.Bits := Status1;
Size1 := Node1^.DataSize;
if Size1 > 0 then
begin
getmem(Ptr1,size1);
DLLGetNodeData(Node1,Ptr1^);
end;
Ecode := DLLChange(Node1,Node2^.DataPtr^,Node2^.DataSize);
Ecode := DLLChange(Node2,Ptr1^,Size1);
if Size1 > 0 then
freemem(Ptr1,Size1);
end; {DLLSwapNodes}
procedure DLLDelAllStatus(BitPos:byte;On:boolean);
{}
var
TempPtr,TempNextPtr: DoubleNodePtr;
begin
if (LinkVars.ActiveDLL <> nil)
and (LinkVars.ActiveDLL^.StartNodePtr <> nil) then with LinkVars.ActiveDLL^ do
begin
TempPtr := StartNodePtr;
TempNextPtr := TempPtr^.NextPtr;
while TempNextPtr <> nil do
begin
if GetBitStatus(TempNextPtr^.Bits,BitPos) = On then
DLLDelNode(TempNextPtr)
else
TempPtr := TempPtr^.NextPtr;
TempNextPtr := TempPtr^.NextPtr;
end;
if GetBitStatus(StartNodePtr^.Bits,BitPos) = On then
DLLDelNode(StartNodePtr);
end;
end; {DLLDelAllStatus}
procedure DLLAdvance(Amount:longint);
{}
var
I : longint;
begin
if (LinkVars.ActiveDLL <> nil) then
for I := 1 to Amount do
if LinkVars.ActiveDLL^.ActiveNodePtr^.NextPtr <> nil then
begin
LinkVars.ActiveDLL^.ActiveNodePtr := LinkVars.ActiveDLL^.ActiveNodePtr^.NextPtr;
inc(LinkVars.ActiveDLL^.ActiveNodeNumber);
end;
end; {DLLAdvance}
procedure DLLRetreat(Amount:longint);
{}
var
I : longint;
begin
if (LinkVars.ActiveDLL <> nil) then
for I := 1 to Amount do
if LinkVars.ActiveDLL^.ActiveNodePtr^.PrevPtr <> nil then
begin
LinkVars.ActiveDLL^.ActiveNodePtr := LinkVars.ActiveDLL^.ActiveNodePtr^.PrevPtr;
dec(LinkVars.ActiveDLL^.ActiveNodeNumber);
end;
end; {DLLRetreat}
function DLLNodePtr(NodeNumber:longint): DoubleNodePtr;
{}
var
StartNode: DoubleNodePtr;
DistanceA,
DistanceB,
DistanceC,
Counter,
I: LongInt;
Forwards : boolean;
Indicator : byte;
begin
if (NodeNumber < 1)
or (LinkVars.ActiveDLL = nil)
or (NodeNumber > LinkVars.ActiveDLL^.TotalNodes) then
DLLNodePtr := nil
else with LinkVars.ActiveDLL^ do
begin
if NodeNumber = 1 then
DLLNodePtr := StartNodePtr
else if NodeNumber = TotalNodes then
DLLNodePtr := EndNodePtr
else if NodeNumber = ActiveNodeNumber then
DLLNodePtr := ActiveNodePtr
else
begin
{check for the nearest node ptr, and jump from there}
DistanceA := abs(NodeNumber - ActiveNodeNumber);
DistanceB := NodeNumber;
DistanceC := TotalNodes - NodeNumber;
if DistanceA < DistanceB then
begin
if DistanceA < DistanceC then
begin
StartNode := ActiveNodePtr;
Forwards := (ActiveNodeNumber < NodeNumber);
Counter := DistanceA;
end
else
begin
StartNode := EndNodePtr;
Forwards := false;
Counter := DistanceC;
end;
end
else {DA > DB}
begin
if DistanceB < DistanceC then
begin
StartNode := StartNodePtr;
Forwards := true;
Counter := pred(DistanceB);
end
else
begin
StartNode := EndNodePtr;
Forwards := false;
Counter := DistanceC;
end;
end;
if Forwards then
for I := 1 to Counter do
StartNode := StartNode^.NextPtr
else
for I := 1 to Counter do
StartNode := StartNode^.PrevPtr;
DLLNodePtr := StartNode;
end;
end;
end; {DLLNodePtr}
procedure DLLJump(NodeNumber:longint);
{}
begin
if LinkVars.ActiveDLL <> nil then
with LinkVars.ActiveDLL^ do
begin
if NodeNumber = 1 then
begin
ActiveNodePtr := StartNodePtr;
ActiveNodeNumber := 1;
end
else
begin
if NodeNumber < ActiveNodeNumber then
DLLRetreat(ActiveNodeNumber - NodeNumber)
else
DLLAdvance(NodeNumber - ActiveNodeNumber);
end;
end;
end; {DLLJump}
procedure DLLShiftActiveNode(NewNode: DoubleNodePtr; NodeNumber: longint);
{}
begin
if LinkVars.ActiveDLL <> nil then
begin
LinkVars.ActiveDLL^.ActiveNodePtr := NewNode;
LinkVars.ActiveDLL^.ActiveNodeNumber := NodeNumber;
end;
end; {DLLShiftActiveNode}
procedure DLLSort(SortID:shortint; Ascending:boolean);
{Shell sort}
var
I,J,Delta : longint;
Swapped : boolean;
Ptr1,Ptr2 : DoubleNodePtr;
begin
if (LinkVars.ActiveDLL <> nil)
and (LinkVars.ActiveDLL^.TotalNodes >= 2) then with LinkVars.ActiveDLL^ do
begin
Delta := TotalNodes div 2;
repeat
repeat
Swapped := false;
Ptr1 := StartNodePtr;
Ptr2 := Ptr1;
for I := 1 to Delta do
Ptr2 := Ptr2^.NextPtr;
for I := 1 to TotalNodes - Delta do
begin
if I > 1 then
begin
Ptr1 := Ptr1^.NextPtr;
Ptr2 := Ptr2^.NextPtr;
end;
if WrongOrder(SortID,Ptr1,Ptr2,Ascending) then
begin
DLLSwapNodes(Ptr1,Ptr2);
Swapped := true;
end;
end;
Until (not Swapped);
Delta := Delta div 2;
Until Delta = 0;
end;
end; {DLLSort}
function DLLGetNodeStr(Node:DoubleNodePtr;Start,Finish: longint): string;
{}
begin
if Node = nil then
DLLGetNodeStr := ''
else
DLLGetNodeStr := LinkVars.ActiveDLL^.GetStr(Node,Start,Finish);
end; {DLLGetNodeStr}
function DLLGetStr(Num:longint): string;
{}
var DNP: DoubleNodePtr;
begin
DNP := DLLNodePtr(Num);
if DNP <> nil then
DLLGetStr := LinkVars.ActiveDLL^.GetStr(DNP,0,0)
else
DLLGetStr := '';
end; {DLLGetStr}
procedure DLLSetBit(Node:DoubleNodePtr; BitPos:byte; On:boolean);
{}
begin
if Node <> nil then
begin
SetBitStatus(Node^.Bits,BitPos,On);
LinkVars.ActiveDLL^.Dirty := true;
end;
end; { DLLSetBit }
function DLLGetBit(Node:DoubleNodePtr; BitPos:byte): boolean;
{}
begin
if Node <> nil then
DLLGetBit := GetBitStatus(Node^.Bits,BitPos)
else
DLLGetBit := false;
end; { DLLGetBit }
function DLLGetTagState(Num:longint):boolean;
{}
var DNP: DoubleNodePtr;
begin
DNP := DLLNodePtr(Num);
if DNP <> nil then
DLLGetTagState := DLLGetBit(DNP,TagBit)
else
DLLGetTagState := false;
end; {DLLGetTagState}
procedure DLLDestroy;
{removes all the memory allocated on the heap by chaining back
through the list and disposing of each node.}
var TempPtr: DoubleNodePtr;
begin
if LinkVars.ActiveDLL <> nil then
begin
TempPtr := LinkVars.ActiveDLL^.EndNodePtr;
if TempPtr <> nil then with LinkVars.ActiveDLL^ do
begin
while TempPtr^.PrevPtr <> nil do
begin
DLLFreeNodeData(TempPtr);
TempPtr := TempPtr^.PrevPtr;
freemem(TempPtr^.NextPtr,sizeof(TempPtr^));
end;
if StartNodePtr <> nil then
begin
DLLFreeNodeData(StartNodePtr);
freemem(StartNodePtr,sizeof(StartNodePtr^));
StartNodePtr := nil;
end;
EndNodePtr := nil;
ActiveNodePtr := nil;
TotalNodes := 0;
ActiveNodeNumber := 0;
end;
end;
end; {DLLDestroy}
function DLLLoadFromFile(Filename:string):integer;
{Opens a file as text, reads in each line as a node, then closes the file
Return codes: 0 all is well!
1 file not found
2 Error Reading file
3 Error creating list
99 No list active
}
var
F: text;
TempStr:string;
begin
if LinkVars.ActiveDLL = nil then
begin
DLLLoadFromFile := 99;
exit;
end;
assign(F, Filename);
{$I-}
reset(F);
{$I+}
if IOResult <> 0 then
DLLLoadFromFile := 1
else
begin
DLLDestroy; {empty the list}
while not eof(F) do
begin
{$I-}
readln(F,TempStr);
{$I+}
if IOResult <> 0 then
begin
close(F);
DLLLoadFromFile := 2;
exit;
end;
if DLLAddStr(TempStr) <> 0 then
begin
close(F);
DLLLoadFromFile := 3;
exit;
end;
end;
close(F);
DLLLoadFromFile := 0;
end;
end; {DLLLoadFromFile}
function DLLSaveToFile(Filename:string):integer;
{Rewrites the file (erasing its contents) then saves the file SLL data
as strings in a text file
Return codes: 0 all is well!
1 Unable to open file
2 Error Writing file
}
var
F: text;
TempStr:string;
Temp1,Temp2: DoubleNodePtr;
begin
assign(F, Filename);
{$I-}
rewrite(F);
{$I+}
if IOResult <> 0 then
DLLSaveToFile := 1
else
begin
Temp1 := LinkVars.ActiveDLL^.StartNodePtr;
while Temp1 <> nil do
begin
Temp2 := Temp1^.NextPtr;
{$I-}
writeln(F,DLLGetNodeStr(Temp1,1,255));
{$I+}
if IOResult <> 0 then
begin
close(F);
DLLSaveToFile := 2;
exit;
end;
Temp1 := Temp2;
end;
close(F);
DLLSaveToFile := 0
end;
end; {DLLSaveToFile}
procedure DLLEmptyList;
{}
begin
DLLDestroy;
end; {DLLEmptyList}
{|||||||||||||||||||||||||||||||||||||||||||||||||||||}
{ }
{ U N I T I N I T I A L I Z A T I O N }
{ }
{|||||||||||||||||||||||||||||||||||||||||||||||||||||}
procedure LinkDefaultSettings;
{}
begin
with LinkVars do
begin
NoFilesFound := 'No Files';
NoDirectories := 'Empty';
end;
end; { LinkDefaultSettings }
procedure GoldLinkInit;
{}
begin
with LinkVars do
begin
ActiveDLL := nil;
ActiveSLL := nil;
LastActiveDLL := nil;
LastActiveSLL := nil;
LastECode := 0;
end;
LinkDefaultSettings;
end; {GoldLinkInit}
begin
GoldLinkInit;
end.